/****************************************************************
 * I am the AC 130 vs Pirate game. I allow the user to control an 
 * AC130 gunship in the hunt for Modern day pirates. The player  
 * will be allowed to roam free across a section of ocean/coastline.  
 * In the water there will be four types of vessels: Merchant  
 * ships that the player must protect, Pirate ships that the player  
 * must identify and destroy, Fishing boats that look like Pirate  
 * ships that the player must not destroy, and Friendly Navy ships  
 * that can capture pirates for extra points. Time permitting there  
 * may also be ground targets to attack. 
 *
 * Key elements of this project will be the Player/AC130, the Ships,  
 * the ShipAI system, the collision grid, the debris controller, the  
 * Ground/Water, Clouds, and scoring system. This project will make  
 * use of an external text file to store useful game parameters,  
 * thus allowing us to play balance the game without recompiling  
 * the executable. 
 *****************************************************************
 * I am the Bullet cotroll class. I contain all the information
 * needed to render the bullets in the game. I read and store all
 * the type data and images. I have functions that 
 *****************************************************************/

#include "BulletCtrl.h"

BulletCtrl::BulletCtrl(){
		// create points
	helper = new Point;
	for(int itor = 0; itor < BULLETMAX; itor++){
		myBullet[itor] = new Bullet;
	}
		// crate last spawn
	lastSpawn = 0;
}


/// I am the destructor
BulletCtrl::~BulletCtrl(){
	delete(helper);
	for(int itor = 0; itor < BULLETMAX; itor++){
		delete(myBullet[itor]);
	}
	
	// set all default bitmaps to temp bitmap
	tempBmp = create_bitmap(64,64);
	for(int itor = 0; itor < BULLETTYPE; itor++){
		tracer[itor] = tempBmp;
		blastMask[itor] = tempBmp;
		for(int itor2 = 0; itor2 < BULLETANIM; itor2++){
			animBlast[itor][itor2] = tempBmp;
			animSplash[itor][itor2] = tempBmp;
		}
	}
}

/// I am the initlizer. I read in all type data from the
/// external type 
void BulletCtrl::Init(GameData * exGd, CrashBin* exCrashBin){
	gd = exGd;
	myCrashBin = exCrashBin;
	// temporary load all types as 20mm
	for(int itor = 0; itor < BULLETTYPE; itor++){
		LoadType( "blt20MM", itor);
	}
}

/// I am the image loader I attach
void BulletCtrl::LoadType(char * pre, int type){
	char total[256];	// editable string
	strncpy(total, pre, 64);
	strncat(total, "speed", 128);
	speed[type] = gd->GetNum(total);

	strncpy(total, pre, 64);
	strncat(total, "maxAnim", 128);
	maxAnim[type] = gd->GetNum(total);

	strncpy(total, pre, 64);
	strncat(total, "maxAge", 128);
	maxAge[type] = gd->GetNum(total);

	strncpy(total, pre, 64);
	strncat(total, "dammage", 128);
	dammage[type] = gd->GetNum(total);

	strncpy(total, pre, 64);
	strncat(total, "killRad", 128);
	killRad[type] = gd->GetNum(total);

	strncpy(total, pre, 64);
	strncat(total, "isTrack", 128);
	isTrack[type] = (gd->GetStr(total)[0] == 't');

	strncpy(total, pre, 64);
	strncat(total, "turnRate", 128);
	turnRate[type] = gd->GetNum(total);


		// load tracer and mask informaion
	strncpy(total, pre, 64);
	strncat(total, "tracer", 128);
	tracer[type] = load_bitmap(gd->GetStr(total), NULL);

	strncpy(total, pre, 64);
	strncat(total, "blastMask", 128);
	blastMask[type] = load_bitmap(gd->GetStr(total), NULL);
	
		// load explosion bitmaps
	for(int itor = 0; itor< maxAnim[type]; itor++){
		strncpy(total, pre, 64);
		strncat(total, "animBlast", 128);
		animBlast[type][itor] = load_bitmap(gd->GetStr(total,itor), NULL);
		strncpy(total, pre, 64);
		strncat(total, "animSplash", 128);
		animSplash[type][itor] = load_bitmap(gd->GetStr(total,itor), NULL);
	}
}

/// I am the spawn bullet function. I create a new bullet
/// and load all the type data into the Bullet after it is
/// placed in the world.
Bullet * BulletCtrl::Spawn(Point * start, Point * target, int type, int loyalty){
	float dist = start->DistTo(target);
	float unitX = (target->x - start->x)/dist;
	float unitY = (target->y - start->y)/dist;
		// use last spawn to find next spawn
	int index = -1;
	for(int itor = 1; itor < BULLETMAX && index == -1; itor++){
		Bullet * tmpPtr = myBullet[(lastSpawn+itor)%BULLETMAX];
		if(tmpPtr->isActive() == false){
			index = (lastSpawn+itor)%BULLETMAX;
		}
	}
		// don't spawn if all are active
	if(index < 0) return NULL;
		// pick bullet to spawn
	Bullet * shoot = myBullet[index];
		// read type data to shoot 
	shoot->speed = speed[type];
	shoot->dammage = dammage[type];
	shoot->killRad = killRad[type];
	shoot->isTrack = isTrack[type];
	shoot->turnRate = turnRate[type];
	shoot->blastMask = blastMask[type]; 
	shoot->maxAnim = maxAnim[type];

		// set starting values
	shoot->center->Copy(start);
	shoot->dx = unitX*speed[type];
	shoot->dy = unitY*speed[type];
	shoot->angle = start->AngTo(target);
	shoot->trackEx = target;
	shoot->timeOut = (int)(dist/speed[type]);	// time out on top of target
	shoot->loyalty = loyalty;
	shoot->type = type;

	return shoot;
}

/// I am the register funciton. I register all active projectiles
/// into the crash bin so that other objects can check on them
void BulletCtrl::RegisterBin(){
	for(int itor = 0; itor < BULLETMAX; itor++){
			// only register exploding bullets
		if(myBullet[itor]->isBoom()){
			myCrashBin->Register(tpBinType::btBullet, itor, 
				myBullet[itor]->center->x, myBullet[itor]->center->y);
		}
	}
}

/// I am the update function. I run the update funciton of
/// all active projectiles
void BulletCtrl::Update(){
	for(int itor = 0; itor < BULLETMAX; itor++){
		myBullet[itor]->Update();
	}
}

/// I am the airborn bullet function I render the
/// bullet at the air level.
void BulletCtrl::Draw(Camera * cam){
	for(int itor = 0; itor < BULLETMAX; itor++){
		if(myBullet[itor]->isActive() //&& 
			//cam->IsInScreen(myBullet[itor]->center)
			)
		{
			cam->WorldPivotCtr(tracer[myBullet[itor]->type],
						myBullet[itor]->center, -myBullet[itor]->angle);
			
		}
	}
}


